package com.mark.service.impl;

import com.alipay.api.response.AlipayTradePrecreateResponse;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.mark.common.Const;
import com.mark.common.ServerResponse;
import com.mark.dao.*;
import com.mark.enums.OrderStatusEnum;
import com.mark.enums.PaymentTypeEnum;
import com.mark.enums.ProductStatusEnum;
import com.mark.enums.PropertiesEnum;
import com.mark.exception.OrderException;
import com.mark.pojo.*;
import com.mark.service.IOrderService;
import com.mark.util.BigDecimalUtil;
import com.mark.util.DateTimeUtil;
import com.mark.util.PropertiesUtil;
import com.mark.vo.OrderItemVo;
import com.mark.vo.OrderProductVo;
import com.mark.vo.OrderVo;
import com.mark.vo.ShippingVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;

/**
 * Created by Mark on 2018/3/29.
 * 订单业务逻辑
 */

@Service("orderServiceImpl")
@Slf4j
public class OrderServiceImpl implements IOrderService{

    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private OrderItemMapper orderItemMapper;
    @Autowired
    private CartMapper cartMapper;
    @Autowired
    private ProductMapper productMapper;
    @Autowired
    private ShippingMapper shippingMapper;
    @Autowired
    private UserMapper userMapper;

    //1.创建订单
    @Override
    public ServerResponse createOrder(Integer currentUserId, Integer shippingId) {
        try {
            //从购物车获取勾选的数据
            List<Cart> cartList = cartMapper.selectCheckedCartByUserId(currentUserId, null);
            Map<Integer, List<Product>> productMap = Maps.newHashMap();
            for (Cart car : cartList) {
                Product product = productMapper.selectByPrimaryKey(car.getProductId());
                int sellerId = product.getOwnerId();
                if (productMap.containsKey(sellerId)) {
                } else {
                    productMap.put(sellerId, null);
                }
            }
            Iterator it = productMap.entrySet().iterator();

            List<Long> orderNumberList = Lists.newArrayList();
            while (it.hasNext()) {
                Map.Entry entry = (Map.Entry) it.next();
                Integer sellerId = (Integer) entry.getKey();
                cartList = cartMapper.selectCheckedCartByUserId(currentUserId, sellerId);

                //构建订单明细
                ServerResponse response = this.getCartOrderItem(currentUserId, cartList);
                if (!response.isSuccess()) {
                    return response;
                }
                List<OrderItem> orderItemList = (List<OrderItem>) response.getData();
                //计算总价
                BigDecimal payment = this.getOrderTotalPrice(orderItemList);

                //构建订单实例
                Order order = this.assembleOrder(currentUserId, shippingId, payment, sellerId);

                if (order == null) {
                    return ServerResponse.createByErrorMessage("生成订单错误");
                }
                for (OrderItem orderItem : orderItemList) {//订单子明细添加OrderNo属性,状态属性
                    orderItem.setOrderNo(order.getOrderNo());
                    orderItem.setEnableStatus(order.getEnableStatus());
                }
                orderItemMapper.batchInsert(orderItemList);

                this.reduceProductStock(orderItemList);//生成成功,减少产品的库存
                //清空一下购物车
                this.cleanCart(cartList);

                //封装返回给前端的Vo
                OrderVo orderVo = assembleOrderVo(order, orderItemList);
                orderNumberList.add(orderVo.getOrderNo());
            }
            return ServerResponse.createBySuccess("新建订单成功！！", orderNumberList);
        }catch (Exception e){
            throw new OrderException("createOrder",e.getClass()+e.getMessage());
        }
    }

    //2.取消订单
    @Transactional
    @Override
    public ServerResponse cancelOrder(Integer currentUserId, Long orderNo) {
        try{
            Order order  = orderMapper.selectOrder(currentUserId,orderNo,null);
            if(order ==null){
                return  ServerResponse.createByErrorMessage("改用户订单不存在");
            }
            if (order.getEnableStatus() != OrderStatusEnum.NO_PAY.getCode()){
                return  ServerResponse.createByErrorMessage("取消清单失败：因为订单已经"+ Const.OrderStatusEnum.codeOf(order.getEnableStatus()).getValue());
            }
            Order updateOrder = new Order();
            updateOrder.setId(order.getId());
            updateOrder.setEnableStatus(OrderStatusEnum.CANCELED.getCode());
            updateOrder.setCloseTime(new Date()); //设置关闭时间
            int rowCount = orderMapper.updateByPrimaryKeySelective(updateOrder);
            if (rowCount > 0){
                return ServerResponse.createBySuccessMessage("取消订单成功");
            }
            return ServerResponse.createByErrorMessage("取消订单失败");
        }catch (Exception e){
            throw new OrderException("cancelOrder",e.getClass()+e.getMessage());
        }
    }

    //3.获取购物车中的商品
    @Override
    public ServerResponse getOrderCartProduct(Integer currentUserId) {
        try{
            List<Cart> cartList = cartMapper.selectCheckedCartByUserId(currentUserId,null);
            ServerResponse response = this.getCartOrderItem(currentUserId,cartList);
            if(!response.isSuccess()){
                return response;
            }
            List<OrderItem> orderItemList = (List<OrderItem>) response.getData();
            List<OrderItemVo> orderItemVoList = Lists.newArrayList();
            BigDecimal payment = new BigDecimal("0");
            for (OrderItem orderItem:orderItemList){
                payment =BigDecimalUtil.add(payment.doubleValue(),orderItem.getTotalPrice().doubleValue());//计算总价
                OrderItemVo orderItemVo = new OrderItemVo();
                orderItemVo = orderItemVo.assembleOrderItemVo(orderItem);
                orderItemVoList.add(orderItemVo);
            }
            OrderProductVo orderProductVo = new OrderProductVo();
            orderProductVo.setProductTotalPrice(payment);
            orderProductVo.setOrderItemVoList(orderItemVoList);
            orderProductVo.setImageHost(PropertiesUtil.getProperty(PropertiesEnum.FTP_SERVICE_HTTP_PREFIX.getPropertiesName()));
            return ServerResponse.createBySuccess(orderProductVo);
        }catch (Exception e){
            throw new OrderException("getOrderCartProduct",e.getClass()+e.getMessage());
        }
    }

    //4.订单详情
    @Override
    public ServerResponse getOrderDetail(Integer currentUserId, Long orderNo,Integer sellerId) {
        try{
            Order order = orderMapper.selectOrder(currentUserId,orderNo,sellerId);
            if (order == null){
                return  ServerResponse.createByErrorMessage("该用户订单不存在");
            }
            List<OrderItem> orderItemList = orderItemMapper.getByOrderNoUserId(orderNo,currentUserId,sellerId);
            OrderVo orderVo = assembleOrderVo(order,orderItemList);
            return ServerResponse.createBySuccess(orderVo);
        }catch (Exception e){
            throw new OrderException("getOrderDetail",e.getClass()+e.getMessage());
        }
    }

    //5.分页获取订单
    @Override
    public ServerResponse getOrderList(Integer currentUserId, int pageNum, int pageSize) {
        try{
            PageHelper.startPage(pageNum,pageSize);
            List<Order> orderList = orderMapper.selectByUserId(currentUserId);
            List<OrderVo> orderVoList = assembleOrderVoList(orderList,currentUserId);
            PageInfo pageResult = new PageInfo(orderList);
            pageResult.setList(orderVoList);
            return ServerResponse.createBySuccess(pageResult);
        }catch (Exception e){
            throw new OrderException("getOrderList",e.getClass()+e.getMessage());
        }
    }

    //admin
    @Override
    public ServerResponse<PageInfo> manageList(int pageNum, int pageSize) {
        try{
            PageHelper.startPage(pageNum,pageSize);
            List<Order> orderList = orderMapper.selectAllOrder();
            List<OrderVo> orderVoList = this.assembleOrderVoList(orderList,null);
            PageInfo pageResult = new PageInfo(orderList);
            pageResult.setList(orderVoList);
            return ServerResponse.createBySuccess(pageResult);
        }catch (Exception e){
            throw new OrderException("manageList",e.getClass()+e.getMessage());
        }
    }

    @Override
    public ServerResponse<OrderVo> manageDetail(Long orderNo) {
        try{
            Order order = orderMapper.selectByOrderNo(orderNo);
            if(order != null){
                List<OrderItem> orderItemList = orderItemMapper.getByOrderNo(orderNo);
                OrderVo orderVo = assembleOrderVo(order,orderItemList);
                return ServerResponse.createBySuccess(orderVo);
            }
            return ServerResponse.createByErrorMessage("订单不存在");
        }catch (Exception e){
            throw new OrderException("manageDetail",e.getClass()+e.getMessage());
        }
    }

    @Override
    public ServerResponse manageSearch(Long orderNo, int pageNum, int pageSize) {
        try{
            PageHelper.startPage(pageNum,pageSize);
            Order order = orderMapper.selectByOrderNo(orderNo);
            if(order != null){
                List<OrderItem> orderItemList = orderItemMapper.getByOrderNo(orderNo);
                OrderVo orderVo = assembleOrderVo(order,orderItemList);
                List<Order> orderList = Lists.newArrayList();
                orderList.add(order);
                List<OrderVo> orderVoList = Lists.newArrayList();
                orderVoList.add(orderVo);
                PageInfo pageResult = new PageInfo(orderList);
                pageResult.setList(orderVoList);
                return ServerResponse.createBySuccess(pageResult);
            }
            return ServerResponse.createByErrorMessage("订单不存在");
        }catch (Exception e){
            throw new OrderException("manageSearch",e.getClass()+e.getMessage());
        }
    }

    //发货
    @Override
    public ServerResponse<String> manageSendGoods(Long orderNo) {
        try{
            Order order= orderMapper.selectByOrderNo(orderNo);
            if(order != null){
                if(order.getEnableStatus() == OrderStatusEnum.PAID.getCode()){//订单转态为已支付
                    order.setEnableStatus(OrderStatusEnum.SHIPPED.getCode());
                    order.setSendTime(new Date());
                    orderMapper.updateByPrimaryKeySelective(order);
                    return ServerResponse.createBySuccessMessage("发货成功");
                }else{
                    return ServerResponse.createByErrorMessage("发货失败：以为该订单的状态为"+ Const.OrderStatusEnum.codeOf(order.getEnableStatus()).getValue());
                }
            }
            return ServerResponse.createByErrorMessage("订单不存在");
        }catch (Exception e){
            throw new OrderException("manageSendGoods",e.getClass()+e.getMessage());
        }
    }

    @Override
    public ServerResponse getSellerOrderList(Integer sellerId, int pageNum, int pageSize) {
        try{
            PageHelper.startPage(pageNum,pageSize);
            List<Order> orderList = orderMapper.selectSellerOrders(sellerId);
            List<OrderVo> orderVoList = this.assembleOrderVoList(orderList,null);
            PageInfo pageResult = new PageInfo(orderList);
            pageResult.setList(orderVoList);
            return ServerResponse.createBySuccess(pageResult);
        }catch (Exception e){
            throw new OrderException("getSellerOrderList",e.getClass()+e.getMessage());
        }
    }

    @Override
    public ServerResponse<String> sellerSendGoods(Long orderNo, Integer sellerId) {
        try{
            Order order= orderMapper.selectByOrderNo(orderNo);
            if(order != null){
                if(order.getEnableStatus() == OrderStatusEnum.PAID.getCode()){//订单转态为已支付
                    order.setEnableStatus(OrderStatusEnum.SHIPPED.getCode());
                    order.setSendTime(new Date());
                    orderMapper.updateByPrimaryKeySelective(order);
                    return ServerResponse.createBySuccess("发货成功");
                }else{
                    return ServerResponse.createByErrorMessage("发货失败：因为该订单的状态为"+ Const.OrderStatusEnum.codeOf(order.getEnableStatus()).getValue());
                }
            }
            return ServerResponse.createByErrorMessage("订单不存在");
        }catch (Exception e){
            throw new OrderException("sellerSendGoods",e.getClass()+e.getMessage());
        }
    }

    //用户确认收货
    @Override
    public ServerResponse getGoods(Integer currentUserId, Long orderNo) {
        try{
            Order order  = orderMapper.selectOrder(currentUserId,orderNo,null);
            if(order ==null){
                return  ServerResponse.createByErrorMessage("该用户订单不存在");
            }
            //判断订单的状态是否为发货的状态
            if (order.getEnableStatus() != OrderStatusEnum.SHIPPED.getCode()){
                return  ServerResponse.createByErrorMessage("确认收货失败：因为订单已经"+ Const.OrderStatusEnum.codeOf(order.getEnableStatus()).getValue());
            }
            Order updateOrder = new Order();
            updateOrder.setId(order.getId());
            updateOrder.setEnableStatus(OrderStatusEnum.ORDER_SUCCESS.getCode());
            updateOrder.setEndTime(new Date()); //设置完成时间
            int rowCount = orderMapper.updateByPrimaryKeySelective(updateOrder);
            if (rowCount > 0){
                return ServerResponse.createBySuccess("谢谢惠顾！");
            }
            return ServerResponse.createByErrorMessage("订单确认收货失败！！！");
        }catch (Exception e){
            throw new OrderException("getGoods",e.getClass()+e.getMessage());
        }
    }

    @Override
    public ServerResponse<PageInfo> sellerSearchOrder(Long orderNo, int pageNum, int pageSize, Integer sellerId) {
        try{
            PageHelper.startPage(pageNum,pageSize);
            Order order = orderMapper.selectByOrderNoAndSellerId(sellerId,orderNo);
            if(order != null){
                List<OrderItem> orderItemList = orderItemMapper.getByOrderNo(orderNo);
                OrderVo orderVo = assembleOrderVo(order,orderItemList);
                List<Order> orderList = Lists.newArrayList();
                orderList.add(order);
                List<OrderVo> orderVoList = Lists.newArrayList();
                orderVoList.add(orderVo);
                PageInfo pageResult = new PageInfo(orderList);
                pageResult.setList(orderVoList);
                return ServerResponse.createBySuccess(pageResult);
            }
            return ServerResponse.createByErrorMessage("订单不存在");
        }catch (Exception e){
            throw new OrderException("sellerSearchOrder",e.getClass()+e.getMessage());
        }
    }

    @Override
    public ServerResponse<PageInfo> searchOrderPayed( int pageNum, int pageSize, Integer sellerId) {
        try{
            PageHelper.startPage(pageNum,pageSize);
            List<Order> orderList =  orderMapper.selectSellerOrdersPayed(sellerId,OrderStatusEnum.PAID.getCode());
            List<OrderVo> orderVoList = this.assembleOrderVoList(orderList,null);
            PageInfo pageResult = new PageInfo(orderList);
            pageResult.setList(orderVoList);
            return ServerResponse.createBySuccess(pageResult);
        }catch (Exception e){
            throw new OrderException("searchOrderPayed",e.getClass()+e.getMessage());
        }
    }

    private List<OrderVo> assembleOrderVoList(List<Order> orderList, Integer currentUserId) {
        try{
            List<OrderVo> orderVoList = Lists.newArrayList();
            for(Order order : orderList){
                List<OrderItem>  orderItemList =Lists.newArrayList();
                if(currentUserId == null){//管理员
                    orderItemList = orderItemMapper.getByOrderNo(order.getOrderNo());
                }else{
                    orderItemList = orderItemMapper.getByOrderNoUserId(order.getOrderNo(),currentUserId,null);
                }
                OrderVo orderVo = assembleOrderVo(order,orderItemList);
                orderVoList.add(orderVo);
            }
            return orderVoList;
        }catch (Exception e){
            throw new OrderException("assembleOrderVoList",e.getClass()+e.getMessage());
        }
    }

    //封装返回前端的VO
    private OrderVo assembleOrderVo(Order order, List<OrderItem> orderItemList) {
        try{
            OrderVo orderVo = new OrderVo();
            orderVo.setShippingId(order.getShippingId());
            orderVo.setOrderNo(order.getOrderNo());
            orderVo.setPayment(order.getPayment());
            orderVo.setPostage(order.getPostage());
            orderVo.setPaymentType(order.getPaymentType());
            orderVo.setPaymentTypeDesc(PaymentTypeEnum.CodeOf(order.getPaymentType()).getInformation());
            orderVo.setStatus(order.getEnableStatus());
            orderVo.setStatusDesc(OrderStatusEnum.codeOf(order.getEnableStatus()).getInformation());

            Shipping shipping = shippingMapper.selectByPrimaryKey(order.getShippingId());
            if (shipping != null){
                orderVo.setReceiverName(shipping.getReceiverName());
                ShippingVo shippingVo = this.assembleShippingVo(shipping);
                orderVo.setShippingVo(shippingVo);
            }
            orderVo.setPaymentTime(DateTimeUtil.dateToStr(order.getPaymentTime()));
            orderVo.setSendTime(DateTimeUtil.dateToStr(order.getSendTime()));
            orderVo.setEndTime(DateTimeUtil.dateToStr(order.getEndTime()));
            orderVo.setCreateTime(DateTimeUtil.dateToStr(order.getCreateTime()));
            orderVo.setCloseTime(DateTimeUtil.dateToStr(order.getCloseTime()));
            orderVo.setImageHost(PropertiesUtil.getProperty(PropertiesEnum.FTP_SERVICE_HTTP_PREFIX.getPropertiesName()));

            List<OrderItemVo> orderItemVoList = Lists.newArrayList();
            for(OrderItem orderItem:orderItemList){
                OrderItemVo orderItemVo = new OrderItemVo();
                orderItemVo = orderItemVo.assembleOrderItemVo(orderItem);
                User seller =  userMapper.selectByPrimaryKey(orderItem.getSellerId());
                if(seller != null){
                    orderItemVo.setSellerName(seller.getUsername());
                }
                orderItemVoList.add(orderItemVo);
            }
            orderVo.setOrderItemVoList(orderItemVoList);
            return orderVo;
        }catch (Exception e){
            throw new OrderException("assembleOrderVo",e.getClass()+e.getMessage());
        }
    }

    private ShippingVo assembleShippingVo(Shipping shipping) {
        try{
            ShippingVo shippingVo = new ShippingVo();
            shippingVo.setReceiverName(shipping.getReceiverName());
            shippingVo.setReceiverAddress(shipping.getReceiverAddress());
            shippingVo.setReceiverProvince(shipping.getReceiverProvince());
            shippingVo.setReceiverCity(shipping.getReceiverCity());
            shippingVo.setReceiverDistrict(shipping.getReceiverDistrict());
            shippingVo.setReceiverZip(shipping.getReceiverZip());
            shippingVo.setReceiverPhone(shipping.getReceiverPhone());
            return shippingVo;
        }catch (Exception e){
            throw new OrderException("assembleShippingVo",e.getClass()+e.getMessage());
        }
    }

    //下单完成后清空购物车中相应的商品
    private void cleanCart(List<Cart> cartList) {
        for (Cart cart:cartList){
            cartMapper.deleteByPrimaryKey(cart.getId());
        }
    }

    //下单完成后减少库存量
    private void reduceProductStock(List<OrderItem> orderItemList) {
        for(OrderItem orderItem:orderItemList){
            Product product = productMapper.selectByPrimaryKey(orderItem.getProductId());
            Integer newProductStock = product.getProductStock()-orderItem.getQuantity();
            product.setProductStock(newProductStock);
            int resultRow = productMapper.updateByPrimaryKeySelective(product);
        }
    }

    //构建订单实例
    private Order assembleOrder(Integer currentUserId, Integer shippingId, BigDecimal payment, Integer sellerId) {
        Order order = new Order();
        long orderNo = this.generateOrderNo();//生成订单号
        order.setUserId(currentUserId);
        order.setShippingId(shippingId);
        order.setSellerId(sellerId);
        order.setOrderNo(orderNo);
        order.setPayment(payment);
        order.setPostage(0);//运费
        order.setEnableStatus(OrderStatusEnum.NO_PAY.getCode());//状态(未支付)
        order.setPaymentType(Const.PaymentTypeEnum.ONLINE_PAY.getCode());

        int rowCount = orderMapper.insert(order);
        if (rowCount > 0){
            return order;
        }
        return  null;
    }

    //自动生成订单号
    private long generateOrderNo() {
        long currentTime = System.currentTimeMillis();
        return currentTime + new Random().nextInt(100);
    }

    //计算订单总价
    private BigDecimal getOrderTotalPrice(List<OrderItem> orderItemList) {
        BigDecimal payment = new BigDecimal("0");
        for(OrderItem orderItem:orderItemList){
            payment = BigDecimalUtil.add(payment.doubleValue(),orderItem.getCurrentUnitPrice().doubleValue());
        }
        return  payment;
    }

    private ServerResponse getCartOrderItem(Integer currentUserId, List<Cart> cartList) {
        List<OrderItem> orderItemList = Lists.newArrayList();
        for (Cart car:cartList){
            Product product = productMapper.selectByPrimaryKey(car.getProductId());
            //检验商品的转态是否在售
            if(ProductStatusEnum.ON_SALE.getStatus() != product.getEnableStatus()){
                return ServerResponse.createByErrorMessage("商品"+product.getProductName()+"不是在售状态！");
            }
            //检查库存量是否大于等于购买量
            if(car.getQuantity()> product.getProductStock()){
                return ServerResponse.createByErrorMessage("您选择的商品"+product.getProductName()+"的库存量不足！");
            }
            //构建orderItem实例
            OrderItem orderItem = new OrderItem();
            orderItem.setUserId(currentUserId);
            orderItem.setProductId(product.getId());
            orderItem.setSellerId(product.getOwnerId());
            orderItem.setProductName(product.getProductName());
            orderItem.setProductImg(product.getMainImgAddr());
            if (product.getPromotionPrice() != null){//如果有现价
                orderItem.setCurrentUnitPrice(product.getPromotionPrice());
            }else{
                orderItem.setCurrentUnitPrice(product.getNormalPrice());
            }
            orderItem.setQuantity(car.getQuantity());
            orderItem.setTotalPrice(BigDecimalUtil.mul(orderItem.getCurrentUnitPrice().doubleValue(),car.getQuantity()));
            orderItemList.add(orderItem);
        }
        return ServerResponse.createBySuccess(orderItemList);
    }

    // 简单打印应答
    private void dumpResponse(AlipayTradePrecreateResponse response) {
        if (response != null) {
            log.info(String.format("code:%s, msg:%s", response.getCode(), response.getMsg()));
            if (StringUtils.isNotEmpty(response.getSubCode())) {
                log.info(String.format("subCode:%s, subMsg:%s", response.getSubCode(),
                        response.getSubMsg()));
            }
            log.info("body:" + response.getBody());

        }

    }
}
